package com.neusoft.hifly.attachment.file.util;

import java.awt.Image;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.MemoryImageSource;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;

import javax.imageio.ImageIO;

import com.neusoft.hifly.core.log.Log;

/**
 * Title: 附件服务
 * <p>
 * Description: 等比例剪裁图片
 * <p>
 * Copyright: 2019
 * <p>
 * Company: 东软汉枫
 *
 * @author lh_neu
 * @version 1.0.0
 */
public class ImageUtil {
	/**
	 * 等比例剪裁图片
	 *
	 * @param originalFile
	 *            图片路径
	 * @param resizedFile
	 *            新的图片路径
	 * @param newWidth
	 *            宽度
	 * @param newHeigth
	 *            高度
	 * @param quality
	 *            图片质量
	 */
	public static void resize(final File originalFile, final File resizedFile, final int newWidth, final int newHeigth,
			final float quality) {
		// 解决原有方式裁剪图片不清晰问题
		AppImageUtil.createThumb2(originalFile.getPath(), resizedFile.getPath(), newWidth, newHeigth);

		//		try {
		//			if (quality > 1) {
		//				throw new IllegalArgumentException("Quality在0到1之间");
		//			}
		//
		//			final String fileType = FileUtil.getSuffix(originalFile.getName());
		//
		//			String canonicalPath = originalFile.getCanonicalPath();
		//
		//			/* 解決bmp文件剪裁问题，转出jpg */
		//			if (".bmp".equalsIgnoreCase(FileUtil.getSuffix(fileType))) {
		//				canonicalPath = resizedFile.getParent() + File.separator + FileUtil.getRandomFileName(".jpg");
		//				ImageUtil.bmpTojpg(originalFile.getPath(), canonicalPath);
		//				resizedFile = new File(CTSaaSAttributes.getWebAppRoot() + GlobalConstants.TEMP_PATH + File.separator
		//						+ FileUtil.getRandomFileName(".jpg"));
		//			}
		//
		//			final ImageIcon ii = new ImageIcon(canonicalPath);
		//			final Image i = ii.getImage();
		//			Image resizedImage = null;
		//
		//			final int iWidth = i.getWidth(null);
		//			final int iHeight = i.getHeight(null);
		//
		//			if (iWidth > iHeight) {
		//				//进行等比例缩放图片
		//				resizedImage = i.getScaledInstance(newWidth, (newWidth * iHeight) / iWidth, Image.SCALE_SMOOTH);
		//			} else {
		//				resizedImage = i.getScaledInstance((newHeigth * iWidth) / iHeight, newHeigth, Image.SCALE_SMOOTH);
		//
		//				/*
		//				 * resizedImage = i.getScaledInstance((newWidth * iWidth) / iHeight, newWidth, Image.SCALE_SMOOTH);
		//				 */
		//			}
		//
		//			// 此代码确保图像中的所有像素都加载
		//			final Image temp = new ImageIcon(resizedImage).getImage();
		//
		//			temp.getWidth(null);
		//			temp.getHeight(null);
		//			BufferedImage bufferedImage = new BufferedImage(temp.getWidth(null), temp.getHeight(null),
		//					BufferedImage.TYPE_INT_RGB);
		//
		//			// 复制图像到了图像
		//			final Graphics g = bufferedImage.createGraphics();
		//
		//			// 清晰的背景和画的形象
		//			g.setColor(Color.white);
		//			g.fillRect(0, 0, temp.getWidth(null), temp.getHeight(null));
		//			g.drawImage(temp, 0, 0, null);
		//			g.dispose();
		//
		//			// 软化
		//			final float softenFactor = 0.05f;
		//			final float[] softenArray = { 0, softenFactor, 0, softenFactor, 1 - (softenFactor * 4), softenFactor, 0,
		//					softenFactor, 0 };
		//			final Kernel kernel = new Kernel(3, 3, softenArray);
		//			final ConvolveOp cOp = new ConvolveOp(kernel, ConvolveOp.EDGE_NO_OP, null);
		//			bufferedImage = cOp.filter(bufferedImage, null);
		//
		//			// 写IPEG到文件
		//			final FileOutputStream out = new FileOutputStream(resizedFile);
		//
		//			// 编码图像为JPEG数据流
		//			final String oldFileName = originalFile.getName();
		//			final String oldFileExt = oldFileName.substring(oldFileName.lastIndexOf(".") + 1);
		//			final BufferedImage im = ImageIO.read(originalFile);
		//			ImageIO.write(im, oldFileExt, out);
		//
		//			/*
		//			 * // 编码图像为JPEG数据流 final JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); final JPEGEncodeParam
		//			 * param = encoder.getDefaultJPEGEncodeParam(bufferedImage); param.setQuality(quality, true);
		//			 * encoder.setJPEGEncodeParam(param); encoder.encode(bufferedImage);
		//			 */
		//
		//		} catch (final Exception e) {
		//			Log.error(e.getMessage());
		//		}
	}

	/**
	 * BMP转JPG
	 *
	 * @param file
	 *            bmp文件路径
	 * @param dstFile
	 *            jpg文件路径
	 */
	public static void bmpTojpg(final String file, final String dstFile) {
		FileOutputStream out = null;
		try {
			final FileInputStream in = new FileInputStream(file);
			final Image TheImage = ImageUtil.read(in);
			final int wideth = TheImage.getWidth(null);
			final int height = TheImage.getHeight(null);
			final BufferedImage tag = new BufferedImage(wideth, height, BufferedImage.TYPE_INT_RGB);
			tag.getGraphics().drawImage(TheImage, 0, 0, wideth, height, null);
			out = new FileOutputStream(dstFile);

			// 解决老版本代码不兼容问题 @author lh_neu
			//			import com.sun.image.codec.jpeg.JPEGCodec;
			//			import com.sun.image.codec.jpeg.JPEGImageEncoder;
			//			final JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			//			encoder.encode(tag);

			final String formatName = dstFile.substring(dstFile.lastIndexOf(".") + 1);
			ImageIO.write(tag, /* "GIF" */ formatName /* format desired */ , new File(dstFile) /* target */ );

		} catch (final Exception e) {
			e.printStackTrace();
		} finally {
			if (out != null) {
				try {
					out.close();
				} catch (final IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	private static int constructInt(final byte[] in, final int offset) {
		int ret = (in[offset + 3] & 0xff);
		ret = (ret << 8) | (in[offset + 2] & 0xff);
		ret = (ret << 8) | (in[offset + 1] & 0xff);
		ret = (ret << 8) | (in[offset + 0] & 0xff);
		return (ret);
	}

	private static int constructInt3(final byte[] in, final int offset) {
		int ret = 0xff;
		ret = (ret << 8) | (in[offset + 2] & 0xff);
		ret = (ret << 8) | (in[offset + 1] & 0xff);
		ret = (ret << 8) | (in[offset + 0] & 0xff);
		return (ret);
	}

	//	private static long constructLong(byte[] in, int offset) {
	//		long ret = ((long) in[offset + 7] & 0xff);
	//		ret |= (ret << 8) | ((long) in[offset + 6] & 0xff);
	//		ret |= (ret << 8) | ((long) in[offset + 5] & 0xff);
	//		ret |= (ret << 8) | ((long) in[offset + 4] & 0xff);
	//		ret |= (ret << 8) | ((long) in[offset + 3] & 0xff);
	//		ret |= (ret << 8) | ((long) in[offset + 2] & 0xff);
	//		ret |= (ret << 8) | ((long) in[offset + 1] & 0xff);
	//		ret |= (ret << 8) | ((long) in[offset + 0] & 0xff);
	//		return (ret);
	//	}

	//	private static double constructDouble(byte[] in, int offset) {
	//		long ret = constructLong(in, offset);
	//		return (Double.longBitsToDouble(ret));
	//	}

	private static short constructShort(final byte[] in, final int offset) {
		short ret = (short) (in[offset + 1] & 0xff);
		ret = (short) ((ret << 8) | (short) (in[offset + 0] & 0xff));
		return (ret);
	}

	static class BitmapHeader {
		public int iSize, ibiSize, iWidth, iHeight, iPlanes, iBitcount, iCompression, iSizeimage, iXpm, iYpm, iClrused,
				iClrimp;

		// 读取bmp文件头信息
		public void read(final FileInputStream fs) throws IOException {
			final int bflen = 14;
			final byte bf[] = new byte[bflen];
			fs.read(bf, 0, bflen);
			final int bilen = 40;
			final byte bi[] = new byte[bilen];
			fs.read(bi, 0, bilen);
			iSize = ImageUtil.constructInt(bf, 2);
			ibiSize = ImageUtil.constructInt(bi, 2);
			iWidth = ImageUtil.constructInt(bi, 4);
			iHeight = ImageUtil.constructInt(bi, 8);
			iPlanes = ImageUtil.constructShort(bi, 12);
			iBitcount = ImageUtil.constructShort(bi, 14);
			iCompression = ImageUtil.constructInt(bi, 16);
			iSizeimage = ImageUtil.constructInt(bi, 20);
			iXpm = ImageUtil.constructInt(bi, 24);
			iYpm = ImageUtil.constructInt(bi, 28);
			iClrused = ImageUtil.constructInt(bi, 32);
			iClrimp = ImageUtil.constructInt(bi, 36);
		}
	}

	private static Image read(final FileInputStream fs) {
		try {
			final BitmapHeader bh = new BitmapHeader();
			bh.read(fs);
			if (bh.iBitcount == 24) {
				return (ImageUtil.readImage24(fs, bh));
			}
			if (bh.iBitcount == 32) {
				return (ImageUtil.readImage32(fs, bh));
			}
			fs.close();
		} catch (final IOException e) {
			Log.error(e.getMessage(), e);
		}
		return (null);
	}

	//24位
	private static Image readImage24(final FileInputStream fs, final BitmapHeader bh) throws IOException {
		Image image;
		if (bh.iSizeimage == 0) {
			bh.iSizeimage = ((((bh.iWidth * bh.iBitcount) + 31) & ~31) >> 3);
			bh.iSizeimage *= bh.iHeight;
		}
		final int npad = (bh.iSizeimage / bh.iHeight) - bh.iWidth * 3;
		final int ndata[] = new int[bh.iHeight * bh.iWidth];
		final byte brgb[] = new byte[(bh.iWidth + npad) * 3 * bh.iHeight];
		fs.read(brgb, 0, (bh.iWidth + npad) * 3 * bh.iHeight);
		int nindex = 0;
		for (int j = 0; j < bh.iHeight; j++) {
			for (int i = 0; i < bh.iWidth; i++) {
				ndata[bh.iWidth * (bh.iHeight - j - 1) + i] = ImageUtil.constructInt3(brgb, nindex);
				nindex += 3;
			}
			nindex += npad;
		}
		image = Toolkit.getDefaultToolkit()
				.createImage(new MemoryImageSource(bh.iWidth, bh.iHeight, ndata, 0, bh.iWidth));
		fs.close();
		return (image);
	}

	//32位
	private static Image readImage32(final FileInputStream fs, final BitmapHeader bh) throws IOException {
		Image image;
		final int ndata[] = new int[bh.iHeight * bh.iWidth];
		final byte brgb[] = new byte[bh.iWidth * 4 * bh.iHeight];
		fs.read(brgb, 0, bh.iWidth * 4 * bh.iHeight);
		int nindex = 0;
		for (int j = 0; j < bh.iHeight; j++) {
			for (int i = 0; i < bh.iWidth; i++) {
				ndata[bh.iWidth * (bh.iHeight - j - 1) + i] = ImageUtil.constructInt3(brgb, nindex);
				nindex += 4;
			}
		}
		image = Toolkit.getDefaultToolkit()
				.createImage(new MemoryImageSource(bh.iWidth, bh.iHeight, ndata, 0, bh.iWidth));
		fs.close();
		return (image);
	}

	//	public static void main(final String[] args) {
	//		final String srcfile = "d://11.jpg";
	//		final String dstFile = "d://22.jpg";
	//
	//		ImageUtil.resize(new File(srcfile), new File(dstFile), 190, 190, 0.7f);
	//		//		ImageUtil.bmpTojpg(srcfile, dstFile);
	//	}
}